#ifndef 	__UPDATER_H__
#define 	__UPDATER_H__

#include <list.h>

#define MAJOR	0
#define MINOR	1

#define UPDATE_MAGIC 310258322

/* field flags definition */
#define FLAG_REG        (1<<0)
#define FLAG_DIR        (1<<1)
#define FLAG_CHR        (1<<2)
#define FLAG_BLK        (1<<3)
#define FLAG_FIFO       (1<<4)
#define FLAG_LINK       (1<<5)
#define FLAG_SOCK       (1<<6)

#define LSEEK_BEGIN     (1) /* Jump to the beginning of update */
#define LSEEK_END       (2) /* Jump to the end of file */
#define LSEEK_NAME      (3) /* Jump to name of update */
#define LSEEK_DESC      (4) /* Jump to the description of update */
#define LSEEK_U_HEADER  (5) /* Jump to update_header */
#define LSEEK_TAGS      (6) /* Jump to tags */
#define LSEEK_SETS      (7) /* Jump to sets */
#define LSEEK_CODE      (8) /* Jump to code */
#define LSEEK_LAST      (9) /* Jump to the last file in update */
#define LSEEK_FIRST     (10) /* Jump to the last file in update */


struct update_header
{
    int     magic;
    char    name[256];     /* Name of the update */
    char    desc[1024];    /* Description, optional */
    int     major;         /* Major number of the update */
    int     minor;         /* Minor number of the update */
    int     id;            /* Current id */
    off_t   tags;         /* Tags, optional */
    off_t   sets;         /* Offset in file of sets */
    off_t   code;         /* Offset in file of code */
    off_t   size;         /* Size of the update without header */
    size_t  tags_size;   /* Size of the tags section */
    size_t  sets_size;   /* Size of the sets section */
    size_t  code_size;   /* Size of the code section */
};

typedef struct update_header update_t;

#define FLAG_REGULAR (1<<0)

/* Every file has such header. */
struct file_header
{
    off_t size;
    unsigned int id; /* Unical id of the file */
    int flags;  /* File type, etc. */
    int perm;   /* Permission, if it relevant for the system */
    int owner;  /* owner of the file */
    int group;  /* Group this file belongs to */
    size_t name_len;
    size_t dir_len;
    char * name;
};

typedef struct file_header file_t;

struct core_struct
{
    que_t * files;          /* Files to add */
    int i_fd_flags;         /* What options used to open file? Need it later on closing */
    int i_fd_out;           /* descriptor of the output file */
    char * pc_update_name;  /* Name of update */
    update_t * ps_update;   /* Read it from update / write back on closing */
};


typedef struct core_struct core_t;

#define SET_FLAG(f, flag) {f->flags |= flag;}
#define CLN_FLAG(f, flag) {f->flags &= ~flag;}

#define COMMAND_ADD         1
#define COMMAND_DEL         2
#define COMMAND_LIST        3
#define COMMAND_MV          4
#define COMMAND_SEARCH      5
#define COMMAND_SET         6
#define COMMAND_CLEAN       7
#define COMMAND_EXTRACT     8
#define COMMAND_INFO        9

#define SUBJECT_FILE        1
#define SUBJECT_DIR         2
#define SUBJECT_FLAG        3

#endif /* 	__UPDATER_H__ */

